/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.extensionpoints.lang.behaviour;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;

import com.cea.papyrus.extensionpoints.lang.AbstractExtensionPoint;
import com.cea.papyrus.extensionpoints.lang.Activator;
import com.cea.papyrus.extensionpoints.lang.ExtensionIds;

/**
 * 
 */
public class BehaviourLanguage extends AbstractExtensionPoint {
	
	/**
	 * 
	 */
	private static final String TAG_LANG = "language";
	// The list of languages registered by dedicated plugins
	/**
	 * 
	 */
	private static BehaviourLanguage[] BehaviourLanguages;
	
	/**
	 * 
	 */
	public final IConfigurationElement	configElement;
	
	/**
	 * 
	 */
	public final int					ordinal;
	
	/**
	 * 
	 */
	public final String langId;
	
	/**
	 * 
	 */
	public final String langLabel;
	
	/**
	 * 
	 */
	private static final String ATT_ID = "id";
	
	/**
	 * 
	 */
	private static final String ATT_LABEL = "label";
	
	/**
	 * 
	 * 
	 * @return 
	 */
	public static BehaviourLanguage[] getBehaviourLanguages() {
				
		if (BehaviourLanguages != null) {
			return BehaviourLanguages;
		}
		
		List<BehaviourLanguage> languages = new ArrayList<BehaviourLanguage>();
				
		// At least one element : Natural (any text) language
		BehaviourLanguage naturalLanguage
				= new BehaviourLanguage("NATURAL", "Natural language");
		languages.add(naturalLanguage);
		
		// Reading data from plugins
		IConfigurationElement[] configElements = Platform
		.getExtensionRegistry()	
		.getConfigurationElementsFor(ExtensionIds.LANG_EXTENSION_ID);
		
		// Read configuration elements for the current extension
		for (int j = 0 ; j < configElements.length ; j++) {
			BehaviourLanguage proxy = parseProfileExtension(configElements[j], languages.size());

			if (proxy != null) {
				languages.add(proxy);
			}
		} // end of configElements loop	
		
		BehaviourLanguages = languages.toArray(new BehaviourLanguage[languages.size()]);
		return BehaviourLanguages;
	}
	
	/**
	 * 
	 * 
	 * @param ordinal 
	 * @param configElt 
	 * 
	 * @return 
	 */
	private static BehaviourLanguage parseProfileExtension(IConfigurationElement configElt, int ordinal) {
		
		if (!configElt.getName().equals(TAG_LANG)) {
			return null;
		}
		
		try {
			return new BehaviourLanguage(configElt, ordinal);
		} catch (Exception e) {
			
			String name = configElt.getAttribute(ATT_ID);
			if (name == null) {
				name = "[missing id attribute]";
			}
			String msg = "Failed to load language with id "
							+ name + " in "
							+ configElt
								.getDeclaringExtension()
								.getExtensionPointUniqueIdentifier();
			
			Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, msg));
											
			return null;
		}
	}
	
	/**
	 * 
	 * 
	 * @param ordinal 
	 * @param configElt 
	 */
	public BehaviourLanguage(IConfigurationElement configElt, int ordinal) {
		this.configElement = configElt;
		this.ordinal = ordinal;
		
		langId = getAttribute(configElt, ATT_ID, "undefined", true);
		langLabel = getAttribute(configElt, ATT_LABEL, "undefined", true);
	}
	
	/**
	 * Default constructor.
	 * 
	 * @param label 
	 * @param uri 	 * @param id 
	 */
	public BehaviourLanguage(String id, String label) {
		this.configElement = null;
		this.ordinal = -1;
		
		langId = id;
		langLabel = label;
	}
}
